// SPDX-License-Identifier: GPL-2.0
#ifndef _NF_SPECIAL_DEF_H
#define _NF_SPECIAL_DEF_H

#include <linux/netfilter.h>
#include <net/netfilter/nf_conntrack_extend.h>

#define DPTS_RANGE_NUM 2
#define TEMPLATE_ACT_POS 2
#define TEMPLATE_RULE_NUM 4

struct nf_conn_template {
	u32 act_map;
	u16 template[TEMPLATE_ACT_POS][TEMPLATE_RULE_NUM];
};

struct nf_conn_ext_port {
	u16 dpts[DPTS_RANGE_NUM];
};

#if defined(CONFIG_ONT_NET_FEATURES) && defined(CONFIG_RTOS_NF_EXTEND)

#define NF_CT_EXT_TEMPLATE_TYPE struct nf_conn_template
#define NF_CT_EXT_CONNPORT_TYPE struct nf_conn_ext_port

#define NF_CT_EXT_TEMPLATE NF_CT_EXT_RESERVE1
#define NF_CT_EXT_CONNPORT NF_CT_EXT_RESERVE3

static inline struct nf_conn_template *nfct_get_template(const struct nf_conn *ct)
{
	return nf_ct_ext_find(ct, NF_CT_EXT_TEMPLATE);
}

static inline struct nf_conn_ext_port *nfct_get_extport(const struct nf_conn *ct)
{
	return nf_ct_ext_find(ct, NF_CT_EXT_CONNPORT);
}

static inline struct nf_conn_template *nfct_add_template(struct nf_conn *ct)
{
	return nf_ct_ext_add(ct, NF_CT_EXT_TEMPLATE, GFP_ATOMIC);
}

static inline struct nf_conn_ext_port *nfct_add_extport(struct nf_conn *ct)
{
	return nf_ct_ext_add(ct, NF_CT_EXT_CONNPORT, GFP_ATOMIC);
}

#else /* CONFIG_ONT_NET_FEATURES && CONFIG_RTOS_NF_EXTEND */

static inline struct nf_conn_template *nfct_get_template(const struct nf_conn *ct)
{
	return NULL;
}

static inline struct nf_conn_ext_port *nfct_get_extport(const struct nf_conn *ct)
{
	return NULL;
}

static inline struct nf_conn_template *nfct_add_template(struct nf_conn *ct)
{
	return NULL;
}

static inline struct nf_conn_ext_port *nfct_add_extport(struct nf_conn *ct)
{
	return NULL;
}

#endif /* CONFIG_ONT_NET_FEATURES && CONFIG_RTOS_NF_EXTEND */

/* Mark expect for ont full cone nat, expanding macro for exp flags.
 * Just see NF_CT_EXPECT_PERMANENT in nf_conntrack_common.h file.
 */
#define NF_CT_EXPECT_FULLCONE 0x80

#endif /* _NF_SPECIAL_DEF_H */
